iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0
Software Development

Rust 學得動嗎系列 第 7

[Day 7] Rust 的泛型和 trait:實現靈活且可重用的程式碼

  • 分享至 

  • xImage
  •  

今天,我們來聊聊 Rust 的泛型(Generics)trait 概念。這些特性使得 Rust 能夠編寫高度抽象且可重用的程式碼,同時保持類型安全和高效率。

泛型

泛型允許我們編寫可以處理多種類型的程式碼,而不是為每種類型都寫一個特定的版本。

泛型函數

fn largest<T: PartialOrd>(list: &[T]) -> &T {
    let mut largest = &list[0];

    for item in list {
        if item > largest {
            largest = item;
        }
    }

    largest
}

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];
    let result = largest(&number_list);
    println!("最大的數字是 {}", result);

    let char_list = vec!['y', 'm', 'a', 'q'];
    let result = largest(&char_list);
    println!("最大的字符是 {}", result);
}

泛型結構體

struct Point<T> {
    x: T,
    y: T,
}

impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }
}

fn main() {
    let integer = Point { x: 5, y: 10 };
    let float = Point { x: 1.0, y: 4.0 };
    println!("x = {}", integer.x());
}

Trait

Trait 定義了一組方法,可以被不同的類型實現。它們類似於其他語言中的接口(Interface)。

定義和實現 trait

trait Summary {
    fn summarize(&self) -> String;
}

struct NewsArticle {
    headline: String,
    location: String,
    author: String,
    content: String,
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}, by {} ({})", self.headline, self.author, self.location)
    }
}

struct Tweet {
    username: String,
    content: String,
    reply: bool,
    retweet: bool,
}

impl Summary for Tweet {
    fn summarize(&self) -> String {
        format!("{}: {}", self.username, self.content)
    }
}

fn main() {
    let tweet = Tweet {
        username: String::from("horse_ebooks"),
        content: String::from("of course, as you probably already know, people"),
        reply: false,
        retweet: false,
    };

    println!("1 new tweet: {}", tweet.summarize());
}

Trait 作為參數

fn notify(item: &impl Summary) {
    println!("Breaking news! {}", item.summarize());
}

Trait Bound

fn notify<T: Summary>(item: &T) {
    println!("Breaking news! {}", item.summarize());
}

多個 Trait Bound

use std::fmt::Display;

fn notify<T: Summary + Display>(item: &T) {
    println!("Breaking news! {}", item);
    println!("Summary: {}", item.summarize());
}

Where 子句

fn some_function<T, U>(t: &T, u: &U) -> i32
    where T: Display + Clone,
          U: Clone + Debug
{
    // 函數體
}

實際應用範例:泛型和 trait 結合使用

讓我們建立一個更複雜的範例,展示如何結合使用泛型和 trait:

use std::fmt::Display;

trait Drawable {
    fn draw(&self);
}

struct Circle {
    radius: f64,
}

struct Rectangle {
    width: f64,
    height: f64,
}

impl Drawable for Circle {
    fn draw(&self) {
        println!("Drawing a circle with radius {}", self.radius);
    }
}

impl Drawable for Rectangle {
    fn draw(&self) {
        println!("Drawing a rectangle with width {} and height {}", self.width, self.height);
    }
}

#[derive(Debug)]
struct Canvas<T: Drawable> {
    shapes: Vec<T>,
}

impl<T: Drawable> Canvas<T> {
    fn new() -> Self {
        Canvas { shapes: Vec::new() }
    }

    fn add_shape(&mut self, shape: T) {
        self.shapes.push(shape);
    }

    fn draw_all(&self) {
        for shape in &self.shapes {
            shape.draw();
        }
    }
}

fn print_info<T: Drawable + Display>(drawable: &T) {
    println!("Info: {}", drawable);
    drawable.draw();
}

fn main() {
    let mut circle_canvas = Canvas::new();
    circle_canvas.add_shape(Circle { radius: 5.0 });
    circle_canvas.add_shape(Circle { radius: 10.0 });

    let mut rectangle_canvas = Canvas::new();
    rectangle_canvas.add_shape(Rectangle { width: 3.0, height: 4.0 });
    rectangle_canvas.add_shape(Rectangle { width: 5.0, height: 6.0 });

    println!("Drawing circles:");
    circle_canvas.draw_all();

    println!("\nDrawing rectangles:");
    rectangle_canvas.draw_all();
}

https://ithelp.ithome.com.tw/upload/images/20240921/20140358yW4rilw5Pb.png

這個例子展示了如何使用 trait 來定義共同行為(Drawable),如何使用泛型來創建可以處理任何 Drawable 類型的 Canvas,以及如何結合多個 trait bound。

明天,我們來聊 Rust 的並行程式設計特性,包括執行緒(threads)和消息傳遞機制。這些特性使得 Rust 能夠高效地處理並行任務,同時保持記憶體安全。


上一篇
[Day 6] Rust 的錯誤處理:優雅地管理失敗
下一篇
[Day 8] Rust 的並行程式設計:安全高效的多執行緒應用
系列文
Rust 學得動嗎30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言